﻿using System;
using System.Text;

namespace Viyi.Util.Codec
{
    /// <summary>
    /// 通过对byte[]和string扩展方法实现对数据按BASE64算法进行编码或解码。
    /// </summary>
    public static class Base64Tool
    {
        /// <summary>
        /// 将2进制数据进行BASE64编码，得到编码文本。
        /// </summary>
        /// <param name="me">源数据</param>
        /// <param name="isBreakLines">是否在编码结果中每76个字符使用换行符进行分隔。</param>
        /// <returns>BASE64编码文本</returns>
        public static string Base64Encode(this byte[] me, bool isBreakLines = false)
        {
            return Convert.ToBase64String(me, isBreakLines
                ? Base64FormattingOptions.InsertLineBreaks
                : Base64FormattingOptions.None);
        }

        /// <summary>
        /// 将2进制数据中的一部分进行BASE64编码，得到编码文本
        /// </summary>
        /// <param name="me">源数据</param>
        /// <param name="start">需要编码的数据起始索引</param>
        /// <param name="length">需要编码的数据长度</param>
        /// <param name="isBreakLines">是否在编码结果中每76个字符使用换行符进行分隔。</param>
        /// <returns>BASE64编码文本</returns>
        public static string Base64Encode(this byte[] me, int start, int length, bool isBreakLines = false)
        {
            return Convert.ToBase64String(me, start, length, isBreakLines
                ? Base64FormattingOptions.InsertLineBreaks
                : Base64FormattingOptions.None);
        }

        /// <summary>
        /// 将BASE64编码文本进行解码，得到原来的2进制数据
        /// </summary>
        /// <param name="me">编码文本</param>
        /// <returns>解码出来的2进制数据</returns>
        public static byte[] Base64Decode(this string me)
        {
            return Convert.FromBase64String(me);
        }

        /// <summary>
        /// 将字符串进行BASE64编码，得到编码文本。
        /// </summary>
        /// <param name="me">需要编码的字符串</param>
        /// <param name="encoding">编码前将源字符串转换成2进制数据的编码方法</param>
        /// <param name="isBreakLines">是否在编码结果中每76个字符使用换行符进行分隔。</param>
        /// <returns>BASE64编码文本</returns>
        public static string Base64Encode(this string me, Encoding encoding = null, bool isBreakLines = false)
        {
            if (string.IsNullOrEmpty(me)) { return me; }

            encoding = encoding ?? Encoding.Default;
            return encoding.GetBytes(me).Base64Encode(isBreakLines);
        }

        /// <summary>
        /// 将字符串进行BASE64编码，得到编码文本。
        /// </summary>
        /// <param name="me">需要编码的字符串</param>
        /// <param name="encoding">编码前将源字符串转换成2进制数据的编码方法</param>
        /// <param name="isBreakLines">是否在编码结果中每76个字符使用换行符进行分隔。</param>
        /// <returns>BASE64编码文本</returns>
        /// <exception cref="ArgumentException">encoding不是有效的代码页名称</exception>
        public static string Base64Encode(this string me, string encoding, bool isBreakLines = false)
        {
            if (string.IsNullOrEmpty(me)) { return me; }

            Encoding encodingObject = Encoding.GetEncoding(encoding);
            return encodingObject.GetBytes(me).Base64Encode(isBreakLines);
        }
    }
}
